#include <stdio.h>

#include "../common_debug.h"
#include <unistd.h>
#include <malloc.h>
#include <stdio.h>
typedef struct linknode
{
    struct linknode *next;
    struct linknode *prev;
} LINKNODE;

typedef struct linklist
{
    int data;
    struct linknode node;
} LINKLIST;

typedef struct linklist1
{
    char data[32];
    struct linknode node;
} LINKLIST1;

#include <malloc.h>

#define PRT_LINKNODE_INFO(linknode) \
    printf("data[%2d], base[%p], prev[%p], next[%p]\n", (linknode)->data, &linknode->node, (linknode)->node.prev, (linknode)->node.next)

#define LINKLIST_INIT(list, n)           \
    {                                    \
        list->node.next = &(list->node); \
        list->node.prev = &(list->node); \
        memcpy(&list->data, &n, sizeof(&list->data));\
    }

#define LINKLIST_HEAD_ADD_NODE(list, add)     \
    {                                         \
        add->node.next = list->node.next;     \
        list->node.next->prev = &(add->node); \
        add->node.prev = &(list->node);       \
        list->node.next = &(add->node);       \
    }

#define LINKLIST_END_ADD_NODE(list, add)      \
    {                                         \
        add->node.next = &(list->node);       \
        add->node.prev = list->node.prev;     \
        list->node.prev->next = &(add->node); \
        list->node.prev = &(add->node);       \
    }

#define INSERT_NODE_HEAD(head, node) \
    {                                \
        (node)->next = (head)->next; \
        (head)->next->prev = (node); \
        (head)->next = (node);       \
        (node)->prev = (head);       \
    }

#define INSERT_NODE_END(head, node)        \
    {                                      \
        (node)->prev = (head)->prev->next; \
        (head)->prev->next = (node);       \
        (head)->prev = (node);             \
        (node)->next = (head);             \
    }


#define container_of(ptr, type, member) ({\
	void *__mptr = (void *)(ptr);\
	((type *)(__mptr - offsetof(type, member))); })

#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

void prt_list(LINKLIST *php)
{
    struct linknode *pos = &php->node;
    LINKLIST *data_unit;
    printf("\n");
    PRT_LINKNODE_INFO(php);
    list_for_each(pos, &php->node)
    {
        data_unit = container_of(pos, LINKLIST, node);
        // 现在你可以访问data_unit->data和其他数据成员了
        PRT_LINKNODE_INFO(data_unit);
    }
}

int main()
{
    LINKLIST *php = (LINKLIST *)malloc(sizeof(LINKLIST));
    LINKLIST_INIT(php, 0);

    for (int i = 1; i < 3; i++)
    {
        LINKLIST *tmp = (LINKLIST *)malloc(sizeof(LINKLIST));
        LINKLIST_INIT(tmp, i);
        INSERT_NODE_END(&(php->node), &(tmp->node));
    }
    LINKLIST1 *tmp = (LINKLIST1 *)malloc(sizeof(LINKLIST1));
    LINKLIST_INIT(tmp, 99);
    INSERT_NODE_END(&(php->node), &(tmp->node));
    prt_list(php);
    return 0;
}

inline void head_insert(LINKNODE *head, LINKNODE *node)
{
    node->next = head->next;
    head->next->prev = node;
    head->next = node;
    node->prev = head;
    return;
}

inline void end_insert(LINKNODE *head, LINKNODE *node)
{
    node->prev = head->prev->next;
    head->prev->next = node;
    head->prev = node;
    node->next = head;
    return;
}
